package com.worldcup.schedule;

import com.worldcup.model.TravelMatching;
import com.worldcup.service.TravelMatchingService;
import com.worldcup.service.TravelService;
import com.worldcup.utils.NamedThreadFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.List;
import java.util.concurrent.*;

/**
 * @author duwan.zq
 * @date 2018/05/23
 */
//@Component
public class TravelMatchingSchedule {

    private final static Logger logger = LoggerFactory.getLogger(TravelMatchingSchedule.class);

    @Autowired
    private TravelService travelService;

    @Autowired
    private TravelMatchingService travelMatchingService;

    private ExecutorService executorService;

    @PostConstruct
    public void init(){
        executorService = new ThreadPoolExecutor(20, 20,
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(), new NamedThreadFactory("travelMatch"));
    }

    @PreDestroy
    public void destroy(){
        if(executorService == null){
            return;
        }
        executorService.shutdown();
    }

    @Scheduled(cron = "0 0 3 * * ?")
    public void matchTravel(){
        List<String> openidList = travelService.getAllOpenid();
        if(CollectionUtils.isEmpty(openidList)){
            logger.info("开始计算行程匹配度, count = 0");
        }
        logger.info("开始计算行程匹配度, count = " + openidList.size());
        for(String openid : openidList){
            executorService.execute(() -> {
                logger.info("开始计算, openid = " + openid);
                openidList.forEach(calOpenid -> {
                    try{
                        Integer matchRate = travelService.calMatching(openid, calOpenid);
                        if(matchRate == null){
                            return;
                        }
                        if(logger.isDebugEnabled()){
                            logger.debug("openid = {}, ref_openid = {}, match_rate = {}", openid, calOpenid, matchRate.intValue());
                        }
                        TravelMatching travelMatching = travelMatchingService.getTravelMatching(openid, calOpenid);
                        if(travelMatching == null){
                            travelMatchingService.insert(new TravelMatching(openid, calOpenid, matchRate));
                        }else if(! matchRate.equals(travelMatching.getMatchRate())){
                            travelMatching.setMatchRate(matchRate);
                            travelMatchingService.update(travelMatching);
                        }
                    }catch (Throwable e){
                        logger.error("openid = {}, ref_openid = {} match error, cause = {}", openid, calOpenid, e.getMessage());
                    }

                });
                logger.info("结束计算, openid = " + openid);
            });



        }
        logger.info("结束计算行程匹配度");
    }


}
